﻿using Furion.Authorization;
using Furion.DataEncryption;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.JsonWebTokens;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace EdgeSearch.Web.Core
{
    public class JwtHandler : AppAuthorizeHandler
    {
        public override Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
        {
            // 这里写您的授权判断逻辑，授权通过返回 true，否则返回 false
            JsonWebToken tokenInfo = null;
            if (JWTEncryption.ValidateJwtBearerToken(httpContext, out tokenInfo))
            {
                return Task<bool>.FromResult(true);
            }

            #region 记录401访问
            var headers = httpContext.Request.Headers;
            var ErpCookie = headers["ErpCookie"];
            var Token = headers["Authorization"];
            var PlatForm = headers["PlatForm"];
            var Mac = headers["Client-Mac"];
            var Version = headers["Client-Version"];
            var Url = httpContext.Request.Path;
            var IP = httpContext.Connection.RemoteIpAddress.ToString();

            @$"
                [状态代码]:401
                [时间]:{DateTime.Now.ToString("G")}
                [JWT签名]:{Token}
                [ERPCookie]:{ErpCookie}
                [PlatForm]:{PlatForm}
                [Mac]:{Mac}
                [Version]:{Version}
                [请求路径]:{Url}
                [客户端IP]:{IP}
            ".LogWarning();
            #endregion
            return Task<bool>.FromResult(false);
        }

        public override async Task HandleAsync(AuthorizationHandlerContext context)
        {
            IEnumerable<IAuthorizationRequirement> pendingRequirements = context.PendingRequirements;
            DefaultHttpContext httpContext = context.GetCurrentHttpContext();
            if (await PipelineAsync(context, httpContext))
            {
                //常规JWT验证
                foreach (IAuthorizationRequirement requirement in pendingRequirements)
                {
                    if (await PolicyPipelineAsync(context, httpContext, requirement))
                    {
                        context.Succeed(requirement);
                    }
                    else
                    {
                        context.Fail();
                    }
                }
            }
            else
            {
                context.Fail();
            }
        }
    }
}
